#include <asm/io.h>

#include "led_operation.h"

/*led0 : GPIO1_IO3*/
static volatile unsigned int *LED0_CCM_CCGRx;
static volatile unsigned int *LED0_IOMUXC_SW_MUX_CTL_PAD_GPIOx_IO0n;
static volatile unsigned int *LED0_GPIOx_GDIR;
static volatile unsigned int *LED0_GPIOx_DR;

/*led1 : GPIO5_IO1 (beep)*/
static volatile unsigned int *LED1_CCM_CCGRx;
static volatile unsigned int *LED1_IOMUXC_SW_MUX_CTL_PAD_GPIOx_IO0n;
static volatile unsigned int *LED1_GPIOx_GDIR;
static volatile unsigned int *LED1_GPIOx_DR;


static int led_board_init(int which)
{
	unsigned int val;
	
	/*初始化led0*/
	if(which == 0)
	{
		if(!LED0_CCM_CCGRx)
		{
			printk("this is led%d init\n", which);
			/*地址映射*/
			LED0_CCM_CCGRx = ioremap(0x20C406C, 4);
			LED0_IOMUXC_SW_MUX_CTL_PAD_GPIOx_IO0n = ioremap(0x20E0068, 4);
			LED0_GPIOx_GDIR = ioremap(0x209C004, 4);
			LED0_GPIOx_DR = ioremap(0x209C000, 4);
		}
		
		/*使能led0的GPIO：GPIO1*/
		*LED0_CCM_CCGRx |= (3 << 26);
		
		/*设置引脚为GPIO功能*/
		val = *LED0_IOMUXC_SW_MUX_CTL_PAD_GPIOx_IO0n;
		val &= ~(0x0f);
		val |= 0x05;
		*LED0_IOMUXC_SW_MUX_CTL_PAD_GPIOx_IO0n = val;
		
		/*设置GPIO为输出：GPIO1_IO3*/
		*LED0_GPIOx_GDIR |= (1 << 3);
	}
	
	/*初始化led1 : 使用蜂鸣器当做第二个led，GPIO5_IO1*/
	else if(which == 1)
	{
		if(!LED1_CCM_CCGRx)
		{
			printk("this is led%d init\n", which);
			/*地址映射*/
			LED1_CCM_CCGRx = ioremap(0x20C406C, 4);
			LED1_IOMUXC_SW_MUX_CTL_PAD_GPIOx_IO0n = ioremap(0x229000C, 4);
			LED1_GPIOx_GDIR = ioremap(0x20AC004, 4);
			LED1_GPIOx_DR = ioremap(0x20AC000, 4);
		}
		
		/*使能led1的GPIO：GPIO1*/
		*LED1_CCM_CCGRx |= (3 << 30);
		
		/*设置引脚为GPIO功能*/
		val = *LED1_IOMUXC_SW_MUX_CTL_PAD_GPIOx_IO0n;
		val &= ~(0x0f);
		val |= 0x05;
		*LED1_IOMUXC_SW_MUX_CTL_PAD_GPIOx_IO0n = val;
		
		/*设置GPIO为输出：GPIO5_IO1*/
		*LED1_GPIOx_GDIR |= (1 << 1);
	}
	
	return 0;
}

static int led_board_ctl(int which, char status)
{
	/*led0控制*/
	if(which == 0)
	{
		if(status == 0){
			*LED0_GPIOx_DR &= ~(1 << 3) ;
		}else{
			*LED0_GPIOx_DR |= (1 << 3) ;
		}
		
	}
	
	/*led1控制：实际上是beep*/
	else if(which == 1)
	{
		if(status == 0){
			*LED1_GPIOx_DR &= ~(1 << 1) ;
		}else{
			*LED1_GPIOx_DR |= (1 << 1) ;
		}
	}

	return 0;
}


static struct led_operations led_board_ops = {
	.num  = 2,
	.init = led_board_init,
	.ctl  = led_board_ctl,
};


void led_board_exit(void)
{
	if(LED0_CCM_CCGRx)
	{
		iounmap(LED0_CCM_CCGRx);
		iounmap(LED0_IOMUXC_SW_MUX_CTL_PAD_GPIOx_IO0n);
		iounmap(LED0_GPIOx_GDIR);
		iounmap(LED0_GPIOx_DR);
	}
	if(LED1_CCM_CCGRx)
	{
		iounmap(LED1_CCM_CCGRx);
		iounmap(LED1_IOMUXC_SW_MUX_CTL_PAD_GPIOx_IO0n);
		iounmap(LED1_GPIOx_GDIR);
		iounmap(LED1_GPIOx_DR);
	}
	printk("led_board_exit\n");
}

struct led_operations *get_board_led_opr(void)
{
	return &led_board_ops;
}



